package com.share.common.utils;

import com.alibaba.fastjson.JSON;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * principal 本金
 * interest 利息
 */

public class RateUtil {
    /**
     * 等额本金 --- 计算
     * <p>
     * 公式：每期应还金额 =(贷款本金÷还款期数)+(贷款本金-已归还本金累计额)×期利率
     *
     * @param loanAmount  借款额金额
     * @param yearRate    年利率
     * @param periodMonth 还款总期数  一个月算一期
     * @return key是第几期数，value是【本期还款额（固定本机+利息[逐年降低]）,本期本金,本期利息,剩余待还总额,累计还款本金 ,累积还款利息】
     */
    public static Map<Integer, Double[]> listEqualPrincipalAmount(double loanAmount, double yearRate, int periodMonth) {
        Map<Integer, Double[]> map = new HashMap();
        // 每期本金
        double principal = new BigDecimal(loanAmount).divide(new BigDecimal(periodMonth), 4, BigDecimal.ROUND_HALF_UP).doubleValue();
        double totalInterest = 0.0;
        double totalPrincipal = 0.0;
        for (int i = 1; i <= periodMonth; i++) {
            //每期利息
            double interest = (loanAmount - principal * (i - 1)) * yearRate / 12.0;
            double monthAmount = principal + interest; //本月应还
            double remainingAmount = loanAmount - principal * i; // 还完本期之后 待还总额

            totalPrincipal += principal;  //累积还款利息
            totalInterest += interest;  //累计还款本金
            //封装结构
            Double[] tmpArr = {new BigDecimal(monthAmount).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(), principal, new BigDecimal(interest).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(), new BigDecimal(remainingAmount).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(), new BigDecimal(totalPrincipal).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(), new BigDecimal(totalInterest).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue()};
            map.put(i, tmpArr);
        }
        return map;
    }


    /**
     * 等额本息
     * 每月还款额 = [贷款本金 × 月利率 × (1 + 月利率)^贷款期数] / [(1 + 月利率)^贷款期数 - 1]
     *
     * @param loanAmount  借款额金额
     * @param yearRate    年利率
     * @param periodMonth 还款总期数  一个月算一期
     * @return key是第几期数，value是【本期还款额（固定本机+利息[逐年降低]）,本期本金,本期利息,剩余待还总额,累计还款本金 ,累积还款利息 】
     */
    public static Map<Integer, Double[]> listEqualPrincipalInterest(double loanAmount, double yearRate, int periodMonth) {
        Map<Integer, Double[]> map = new HashMap();
        //计算临时利率
        double monthRate = yearRate / 12.0;
        double tmpRatio = Math.pow(1 + monthRate, periodMonth);
        double monthAmount = loanAmount * monthRate * tmpRatio / (tmpRatio - 1);
        double remainingAmount = loanAmount;
        double totalInterest = 0.0;
        double totalPrincipal = 0.0;
        for (int i = 1; i <= periodMonth; i++) {
            double interest = remainingAmount * monthRate;//本息
            double principal = monthAmount - interest;//本金
            remainingAmount -= principal;// 还完本期之后 待还总额

            totalPrincipal += principal;  //累积还款利息
            totalInterest += interest;  //累计还款本金
            //封装结构
            Double[] tmpArr = {new BigDecimal(monthAmount).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(), new BigDecimal(principal).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(), new BigDecimal(interest).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(), new BigDecimal(remainingAmount).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(), new BigDecimal(totalPrincipal).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(), new BigDecimal(totalInterest).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue()};
            map.put(i, tmpArr);
        }
        return map;
    }


    public static void main(String[] args) {
        double invest = 51000; // 本金
        int periodNum = 12; // 期数
        double yearRate = 0.12775; // 年利率
        Map<Integer, Double[]> listEqualPrincipalInterest = listEqualPrincipalInterest(invest, yearRate, periodNum);
        Map<Integer, Double[]> listEqualPrincipalAmount = listEqualPrincipalAmount(invest, yearRate, periodNum);

        System.out.println("等额本金：" + JSON.toJSONString(listEqualPrincipalAmount));
        System.out.println("等额本息：" + JSON.toJSONString(listEqualPrincipalInterest));
    }
}
